Skip to main content

OOP with Microservices

OOP focuses on designing software using objects that:

  • Encapsulate data and behavior
  • Follow principles like encapsulation, abstraction, inheritance, and polymorphism
  • Promote modularity, reuse, and maintainability

Microservices and modular monoliths focus on system-level modularity:

  • Dividing a large system into independent components (services or modules)
  • Minimizing coupling and maximizing cohesion

OOP works inside these architectural styles to structure the code within each service or module.

OOP in Microservices​

A microservices system consists of:

  • Many small, independent services
  • Each service owns its data and business logic
  • Services communicate via APIs or messaging

Each microservice is often a mini object-oriented application.

How OOP Fits​

Inside each microservice:

  • Use classes and objects to model domain concepts.
  • Apply SOLID principles.
  • Use Clean / Hexagonal / Onion Architecture inside each service.
  • Treat the microservice itself as a high-level module.

Example: E-commerce System with Microservices​

Services:

  • Order Service
  • Payment Service
  • Inventory Service

Inside the Order Service (OOP Design)​

Domain Entity​

public class Order {
private int orderId;
private List<Item> items;

public double calculateTotal() {
return items.stream().mapToDouble(Item::getPrice).sum();
}
}

Service Class​

public class OrderService {
private final OrderRepository orderRepository;
private final PaymentClient paymentClient;

public OrderService(OrderRepository orderRepository, PaymentClient paymentClient) {
this.orderRepository = orderRepository;
this.paymentClient = paymentClient;
}

public void placeOrder(Order order) {
paymentClient.charge(order.calculateTotal());
orderRepository.save(order);
}
}

Repository​

public interface OrderRepository {
void save(Order order);
}
  • OOP structures the internal logic.
  • The microservice boundary is the system-level encapsulation.
  • The service communicates with others via APIs, not direct object calls.

Key OOP Benefits in Microservices​

OOP PrincipleBenefit in Microservices
EncapsulationEach service hides its internal structure
AbstractionAPIs and interfaces define contracts
Single ResponsibilityEach service and class has a focused role
PolymorphismEnables flexible implementations (e.g., multiple payment gateways)

OOP in Modular Monoliths​

A modular monolith:

  • Is deployed as one application
  • Internally structured as independent modules
  • Each module has its own domain, logic, and persistence
  • Modules communicate through explicit interfaces, not shared internals

It combines the simplicity of monoliths with the structure of microservices.

How OOP Fits​

OOP helps:

  • Model each module as a bounded context.
  • Enforce encapsulation at the module level.
  • Design clean interfaces between modules.
  • Prevent tight coupling between domains.

Example: Modular Monolith E-commerce System​

Modules:

  • Order Module
  • Payment Module
  • Inventory Module

Inside the Order Module

Domain Entity​

public class Order {
private int id;
private List<Item> items;

public double total() {
return items.stream().mapToDouble(Item::getPrice).sum();
}
}

Application Service​

public class OrderService {
private final PaymentPort paymentPort;
private final InventoryPort inventoryPort;

public OrderService(PaymentPort paymentPort, InventoryPort inventoryPort) {
this.paymentPort = paymentPort;
this.inventoryPort = inventoryPort;
}

public void placeOrder(Order order) {
inventoryPort.reserveItems(order.getItems());
paymentPort.charge(order.total());
// Save order
}
}

Interfaces Between Modules

public interface PaymentPort {
void charge(double amount);
}

public interface InventoryPort {
void reserveItems(List<Item> items);
}

Implementations in Other Modules

public class PaymentService implements PaymentPort {
public void charge(double amount) {
// Payment logic
}
}
public class InventoryService implements InventoryPort {
public void reserveItems(List<Item> items) {
// Inventory logic
}
}
  • Modules depend on interfaces, not concrete implementations.
  • This enforces compile-time boundaries, similar to microservices but without network overhead.
  • OOP principles ensure clean separation and testability.

Microservices vs Modular Monolith (OOP Perspective)​

AspectMicroservicesModular Monolith
DeploymentMultiple independent servicesSingle deployable unit
CommunicationNetwork (HTTP, messaging)In-process calls
OOP RoleStructures each service internallyStructures each module internally
EncapsulationEnforced by service boundaryEnforced by code/module boundaries
ComplexityHigher (distributed systems)Lower (single runtime)

Key Design Principles Connecting OOP to Both​

  1. Encapsulation at multiple levels
    • Class → Module → Service
  2. Abstraction via interfaces
    • Allows substituting implementations
    • Enables testing and decoupling
  3. High cohesion, low coupling
    • Core goal in both OOP and system architecture
  4. Domain-Driven Design (DDD)
    • Aligns naturally with OOP and modular architectures
    • Each bounded context maps to a module or microservice

Summary​

OOP provides the foundation for structuring logic inside services or modules, while microservices and modular monoliths define how those components are organized at the system level.

  • In microservices, each service is an independent object-oriented system.
  • In a modular monolith, OOP enforces clean boundaries within a single deployable application.